# -*- coding: utf-8 -*-
"""
场景生成器 - 使用LLM从Markdown生成场景
"""

import re
from typing import Any, Dict, Optional


class SceneGenerator:
    """场景生成器"""

    def __init__(self, provider):
        """
        初始化生成器

        Args:
            provider: LLM Provider实例
        """
        self.provider = provider

    def generate(self, markdown_text: str) -> Optional[Dict[str, Any]]:
        """
        生成场景数据

        Args:
            markdown_text: Markdown文本

        Returns:
            场景数据字典
        """
        prompt = self._build_prompt(markdown_text)
        messages = [
            {"role": "system", "content": "你只需输出 JSON，不要任何解释。"},
            {"role": "user", "content": prompt},
        ]

        content = self.provider.chat(messages, temperature=0.2)
        if not content:
            return None

        # 尝试解析JSON
        obj = self._try_load_json_loose(content or "")
        if obj and self._validate_scenes_obj(obj):
            return obj

        return None

    def _build_prompt(self, markdown_text: str) -> str:
        """构建提示词"""
        return (
            "你是一名教学视频的脚本结构化助手。\n"
            "请将下面的 Markdown 文档转换为用于生成视频的场景 JSON，严格遵循以下结构：\n"
            "{\n"
            "  \"version\": \"1.0\",\n"
            "  \"meta\": {\"title\": \"...\", \"language\": \"zh-CN\"},\n"
            "  \"scenes\": [\n"
            "    {\n"
            "      \"id\": \"scene-001\",\n"
            "      \"title\": \"...\",\n"
            "      \"narration\": \"分镜讲述文本，尽量口语化\",\n"
            "      \"duration_hint_sec\": 8.0,\n"
            "      \"visuals\": [ { \"type\": \"text\", \"content\": \"...\" } ]\n"
            "    }\n"
            "  ]\n"
            "}\n"
            "输出要求：只输出 JSON（不需要解释、不要代码块围栏）。\n\n"
            "Markdown 文档：\n" + markdown_text
        )

    def _try_load_json_loose(self, text: str) -> Optional[Dict[str, Any]]:
        """宽松地加载JSON"""
        t = text.strip()
        t = re.sub(r"^```(?:json|javascript|python)?\n|\n```$", "", t)

        try:
            return json.loads(t)
        except Exception:
            # 查找第一个{...}块
            m = re.search(r"\{[\s\S]*\}", t)
            if m:
                try:
                    return json.loads(m.group(0))
                except Exception:
                    return None
        return None

    def _validate_scenes_obj(self, obj: Dict[str, Any]) -> bool:
        """验证场景对象"""
        if not isinstance(obj, dict):
            return False

        scenes = obj.get("scenes")
        if not isinstance(scenes, list) or not scenes:
            return False

        for s in scenes:
            if not isinstance(s, dict):
                continue
            title = (s.get("title") or "").strip()
            narration = (s.get("narration") or "").strip()
            if title or narration:
                return True

        return False
